/*
 * Project Name: feui
 * File Name: DataGridTag.java
 * Copyright: Copyright(C) 1985-2014 ZKTeco Inc. All rights reserved.
 */
package com.xdtech.web.freemark.tags;

import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;

import com.xdtech.common.utils.ApplicationContextUtil;
import com.xdtech.common.utils.JsonUtil;
import com.xdtech.core.init.InitCacheData;
import com.xdtech.core.orm.utils.BeanUtils;
import com.xdtech.web.freemark.item.GridColumn;
import com.xdtech.web.freemark.item.OperationItem;
import com.xdtech.web.model.ComboBox;

import freemarker.core.Environment;
import freemarker.template.TemplateDirectiveBody;
import freemarker.template.TemplateException;

/**
 * easyui datagrid 自定义标签
 * @author <a href="max.zheng@zkteco.com">郑志雄</>
 * @version 1.0.0
 * @since 2014-9-11 下午6:05:45
 */
public class TreeGridTag extends EasyUiTag
{
//	<table id="materialCategory_list" data-options="border:false"></table>
//	<script type="text/javascript">
//	var materialCategory_list = null;
//	$(function(){
//		materialCategory_list = $('#materialCategory_list');
//		materialCategory_list.treegrid({
////				title:'TreeGrid with Footer',
////				iconCls:'icon-ok',
//			loadMsg : '数据加载中，请稍等...',
//			toolbar : '#materialCategorylist_search',
//			height : 'auto',
//			striped : 'false',
//			fit : true,
//			selectOnCheck : false,
//			checkOnSelect : false,
//			rownumbers: true,
//			animate:true,
//			collapsible:true,
//			fitColumns:true,
//			url:'materialCategory.do?loadTreeList',
//			method: 'get',
//			idField:'id',
//			treeField:'code',
//			showFooter:true,
//			columns : [ [ {
//				field : 'id',
//				checkbox : true
//			}, {
//				field : 'code',
//				width : 100,
//				title : '编码',
//				sortable : true,
//			}, {
//				field : 'name',
//				width : 100,
//				title : '名称',
//				sortable : true,
//			}, ] ],
//		});
//	})
//</script>

	/*
	 * (非 Javadoc)
	 * render
	 * <p>对override方法的补充说明，若不需要则删除此行</p>
	 * 
	 * @param env
	 * 
	 * @param params
	 * 
	 * @param body
	 * 
	 * @throws IOException
	 * 
	 * @throws TemplateException
	 * 
	 * @see com.zzx.freemark.tag.SecureTag#render(freemarker.core.Environment, java.util.Map, freemarker.template.TemplateDirectiveBody)
	 */
	@Override
	public void render(Environment env, Map params, TemplateDirectiveBody body) throws IOException, TemplateException
	{

		try
		{
			String className = params.get("item").toString();
			boolean pagination = params.get("pagination") != null ? Boolean.valueOf(params.get("pagination").toString()) : false;
			boolean isEditable= params.get("autoEditing")!= null ? Boolean.valueOf(params.get("autoEditing").toString()):false;

			String tableId = params.get("id") == null ? UUID.randomUUID().toString() : params.get("id").toString();
			StringBuffer sb = new StringBuffer("<table id=\"" + tableId + "\" data-options=\"border:false\"></table>");
			sb.append("<script type=\"text/javascript\">")
					.append("var "+tableId+" = null;")
					.append("$(function() {")
					.append(tableId+" = $('#"+tableId+"');")
					.append(tableId+".treegrid({")
					.append(addProperties("url", params.get("url"), true))
					.append(addProperties("height", "auto", true))
					.append(addProperties("title",params.get("title"),true))
					.append(addProperties("striped", "false", true))
					.append(addProperties("fit", "true", false))
					.append(addProperties("selectOnCheck", params.get("selectOnCheck")!= null ? params.get("selectOnCheck"):false, false))//勾选checkbox自动选中当前行，默认是false
					.append(addProperties("checkOnSelect", params.get("checkOnSelect")!= null ? params.get("checkOnSelect"):false, false))//选中当前行自动勾选checkbox，默认是false
					.append(addProperties("toolbar", params.get("toolbar"), true))
					.append(addProperties("loadMsg", "数据加载中，请稍等...", true))
					.append(addProperties("queryParams", params.get("queryParams")!=null?params.get("queryParams"):"{time : new Date().getTime()}", false))
					.append(addProperties("rownumbers", params.get("rownumbers")!= null ? params.get("rownumbers"):true, false))
					.append(addProperties("animate", params.get("animate")!= null ? params.get("animate"):true, false))
					.append(addProperties("collapsible", params.get("collapsible")!= null ? params.get("collapsible"):true, false))
					.append(addProperties("fitColumns", params.get("fitColumns")!= null ? params.get("fitColumns"):true, false))
					.append(addProperties("singleSelect", params.get("singleSelect")!= null ? params.get("singleSelect"):true, false))
					.append(addProperties("checkbox", params.get("checkbox"), false))
					.append(addProperties("idField", params.get("idField")!= null ? params.get("idField"):"id", true))
//					.append(addGridEditable(params,isEditable,tableId))//添加表格编辑功能
					.append(addProperties("treeField", params.get("treeField")!= null ? params.get("treeField"):"code", true))
					.append(addProperties("showFooter", params.get("showFooter")!= null ? params.get("showFooter"):true, false))
					.append(addEvent(params))
					.append(createPagination(pagination))
					.append(createColumns(className,params.get("idField")!=null,params.get("operations"),isEditable))
					.append("});");
			if (pagination)
			{
				sb.append("$('#"+tableId+"').datagrid('getPager').pagination({")
				  .append("beforePageText: '第',") //页数文本框前显示的汉字  
			      .append("afterPageText: '页    共 {pages} 页',")
			      .append("displayMsg: '当前显示 {from} - {to} 条记录   共 {total} 条记录',")
			      .append("});");   
			}
			//添加列表默认刷新方法
//			sb.append("function "+tableId+"_refresh() { "+tableId+".datagrid('reload'); }");
			
			
			sb.append("});");
			sb.append("</script>");
			// 真正开始处理输出内容
			writeBody(env, sb.toString());
		}
		catch (Exception e)
		{
			
		}

	}

	

	/**
	 * 
	 * @author max.zheng
	 * @create 2015-1-27下午9:59:50
	 * @modified by
	 * @param params
	 * @return
	 */
	private String addGridEditable(Map params,Boolean isEditable,String tableId) {
		StringBuffer sb = new StringBuffer();
		if (isEditable) {
			sb.append(addProperties("autoEditing",isEditable, false))
			  .append(addProperties("singleEditing", params.get("singleEditing")!= null ? params.get("singleEditing"):false, false))
			  .append(addProperties("extEditing", params.get("extEditing")!= null ? params.get("extEditing"):true, false))
			  .append("rowContextMenu: [{ text: \"编辑\", iconCls: \"icon-edit\", handler: function (e, index) { "+tableId+".datagrid(\"beginEdit\", index); } }],");
		}

		return sb.toString();
	}



	/**
	 * 添加事件相关操作
	 * @author max.zheng
	 * @create 2014-9-29下午9:23:33
	 * @modified by
	 * @param params
	 * @return
	 */
	private String addEvent(Map params) {
		StringBuffer sb = new StringBuffer();
		if (params.get("onClickRow")!=null) {
			sb.append("onClickRow: function(rowData){"+params.get("onClickRow")+";},");
		}
		if (params.get("onDblClickRow")!=null) {
			sb.append("onDblClickRow: function(rowData){"+params.get("onDblClickRow")+";},");
		}
		return sb.toString();
	}



	private String createPagination(boolean pagination)
	{
		StringBuffer sb = new StringBuffer();
		if (pagination)
		{
			sb.append("pageSize: 50,") 				//每页显示的记录条数，默认为10
			.append("pageList:[50, 100, 200, 500,800],") //可以设置每页记录条数的列表
			.append("pagination:true,");
		}
		return sb.toString();
	}

	protected String createColumns(String className,boolean showChecked,Object operations,Boolean isEditable) throws ClassNotFoundException
	{
		Class itemCls = Class.forName(className);
//		Class parentCls =  itemCls.getSuperclass();
//		Field[] parentFields = parentCls.getDeclaredFields();
		Field[] fields = itemCls.getDeclaredFields();
		StringBuffer sb = new StringBuffer("columns:[[");
		if (showChecked) {
			sb.append("{field : 'id',checkbox : true},");
		}
//		for (Field field : parentFields)
//		{
//			createColumn(showChecked, isEditable, sb, field);
//		}
		
		for (Field field : fields)
		{
			createColumn(showChecked, isEditable, sb, field);
		}
		
		if (operations!=null&&!operations.toString().trim().equals("")) {
			List<OperationItem> items = JsonUtil.getDTOList(operations.toString(), OperationItem.class);
			StringBuffer operationItems = new StringBuffer("var rowId = row.id;var str = '';str +='");
			for (OperationItem item : items) {
//				<img  onclick=\"lookUserInfo('+rowId+')\" src=\"plugins/xdtech/images/notes/note.png\" title=\"查看\"/>
				//权限过滤
				if (StringUtils.isEmpty(item.getShiro())||(SecurityUtils.getSubject().isPermitted(item.getShiro()))) {
					operationItems.append("<img  onclick=\""+item.getOnClick()+"('+rowId+')\" src=\""+item.getSrc()+"\" title=\""+item.getTitle()+"\"/>&nbsp;");
				}
			}
			operationItems.append("';return str;");
			sb.append("{field :'action',title : '操作',width : 200,formatter : function(value, row, index) {"+operationItems+"}},");
		}
		sb.append("]],");
		return sb.toString();
	}



	/**
	 * 
	 * @author max.zheng
	 * @create 2015-7-10下午10:17:22
	 * @modified by
	 * @param showChecked
	 * @param isEditable
	 * @param sb
	 * @param field
	 */
	private void createColumn(boolean showChecked, Boolean isEditable,
			StringBuffer sb, Field field) {
		GridColumn gridColumn = field.getAnnotation(GridColumn.class);
		//新增列表是否显示控制,主要是解决部分情况下表格查询数据不需要直接显示控制 add by max 20151121
		if (gridColumn != null&&gridColumn.show())
		{
			sb.append("{field:'" + field.getName() + "',width:"+gridColumn.width()+",title:'" + gridColumn.title()+"',sortable: true,");
			//供内嵌编辑使用的下拉框选项  add by max 20150614
			String editData = "[";
			if (gridColumn.formatter()!=null&&gridColumn.formatter().length>0) {
				sb.append("formatter:function(value, row, index) {");
				for (int i = 0; i < gridColumn.formatter().length; i++) {
					String kv = gridColumn.formatter()[i];
					String[] kval = kv.split("=",2);
//						kval[1] = kval[1].replaceAll("", replacement)
					if (i==0) {
						sb.append("if ((value+'')=='"+kval[0]+"') { return '"+kval[1]+"'; }"); 
					}else if (showChecked) {
						sb.append("else if ((value+'')=='"+kval[0]+"') { return '"+kval[1]+"'; }"); 
					}else {
						sb.append("else { return '--';}");
					}
				
				}
				sb.append("},");
			}
			else if (gridColumn.formatter().length==0&&!gridColumn.dictionaryCode().equals(""))
			{
				//扩展数据字典
				sb.append("formatter:function(value, row, index) { var rv = '';");
				List items = InitCacheData.dictionary.get(gridColumn.dictionaryCode());
				List<ComboBox> comboBoxs = BeanUtils.copyListProperties(ComboBox.class, items);
				for (int i = 0; i < comboBoxs.size(); i++)
				{
					ComboBox cb = comboBoxs.get(i);
					if (i==0) {
						sb.append("if ((value+'')=='"+cb.getValue()+"') { return '"+cb.getName()+"'; }"); 
					}else if (showChecked) {
						sb.append("else if ((value+'')=='"+cb.getValue()+"') { return '"+cb.getName()+"'; }"); 
					}else {
						sb.append("else { return '--';}");
					}
					editData += "{'"+field.getName()+"': '"+cb.getValue()+"', 'name': '"+cb.getName()+"' },";
//					sb.append("if((value+'').indexOf('"+cb.getValue()+"')>=0) {rv += ' "+cb.getName()+"';}");

				}
				editData += "]";
				sb.append("return rv;},");
			}else if (!gridColumn.javaFormatter().equals("")) {
				//扩展数据字典
				sb.append("formatter:function(value, row, index) { var rv = '';");
				//新增自定义代码动态格式化功能，扩展了内嵌编辑下拉框  add by max 20160306
				List<ComboBox> comboBoxs = createByJavaFormatter(gridColumn.javaFormatter());
				for (int i = 0; i < comboBoxs.size(); i++)
				{
					ComboBox cb = comboBoxs.get(i);
					if (i==0) {
						sb.append("if ((value+'')=='"+cb.getValue()+"') { return '"+cb.getName()+"'; }"); 
					}else if (showChecked) {
						sb.append("else if ((value+'')=='"+cb.getValue()+"') { return '"+cb.getName()+"'; }"); 
					}else {
						sb.append("else { return '--';}");
					}
					editData += "{'"+field.getName()+"': '"+cb.getValue()+"', 'name': '"+cb.getName()+"' },";
//					sb.append("if((value+'').indexOf('"+cb.getValue()+"')>=0) {rv += ' "+cb.getName()+"';}");

				}
				editData += "]";
				sb.append("return rv;},");
			}
			if (isEditable&&gridColumn.dictionaryCode().equals("")&&gridColumn.javaFormatter().equals("")) {
				//目前先支持文本内嵌编辑
				sb.append("editor : {type : 'text'}");
			}else if(isEditable&&!gridColumn.dictionaryCode().equals("")
					||isEditable&&!gridColumn.javaFormatter().equals("")){
				//data:[{ "ltype": "ac", "lid": "空调" }, { "ltype": "tv", "lid": "电视" }],
				sb.append("editor : {type : 'combobox',options:{valueField:'"+field.getName()+"',textField:'name',data:"+editData+",required:true}}");
			}
			sb.append("},");
		}
	}



	/**
	 * 根据java配置获取下拉框列表
	 * @author max.zheng
	 * @create 2016-3-6下午4:12:55
	 * @modified by
	 * @param javaFormatter
	 * @return
	 */
	private List<ComboBox> createByJavaFormatter(String javaFormatter) {
		List<ComboBox> comboBoxs = new ArrayList<ComboBox>();
		try {
			Object object = null;
			Class clazz = null;
			String[] classWithMethod = javaFormatter.split("#");
			if (StringUtils.isNotBlank(classWithMethod[0])) {

				object = ApplicationContextUtil.getContext().getBean(
						classWithMethod[0]);

				if (object == null) {

					clazz = Class.forName(classWithMethod[0]);
					object = clazz.newInstance();
				}
			}

			if (object == null) {
				return comboBoxs;
			}
			clazz = object.getClass();
			Method method = clazz.getDeclaredMethod(classWithMethod[1]);
			if (method != null) {
				comboBoxs = (List<ComboBox>) method.invoke(object);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return comboBoxs;
	}
}
